/*******************************************************************************
 * (c) Copyright 2017 lvxi. All Rights Reserved.
 ******************************************************************************/

package edu.jxufe.nb112.blog.web.controller;

import edu.jxufe.nb112.blog.core.persist.entity.FtlTemplate;
import edu.jxufe.nb112.blog.core.persist.entity.SysConfig;
import edu.jxufe.nb112.blog.core.persist.service.FtlTemplateService;
import edu.jxufe.nb112.blog.core.persist.service.user.SysConfigService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Controller
@RequestMapping("ftl")
public class FtlTemplateController extends BaseController{
    private final static Logger LOG = LoggerFactory.getLogger(FtlTemplateController.class.getName());

    @Autowired
    FreeMarkerConfigurer freeMarkerConfigurer;

    @Autowired
    FtlTemplateService ftlTemplateService;

    @Autowired
    SysConfigService sysConfigService;

    @RequestMapping("make")
    @ResponseBody
    public Object make(Long ftlTemplateId) {
        FtlTemplate ftlTemplate = ftlTemplateService.getFtlTemplateById(ftlTemplateId);
        if (ftlTemplate != null) {
            Configuration cfg = freeMarkerConfigurer.getConfiguration();
            try {
                Template temp = cfg.getTemplate(ftlTemplate.getLocation()+".ftl");
                String tempStr = temp.toString();
                Map<String, Object> lyt = new HashMap<String, Object>();

                String[] ret = footerJavaScript(tempStr);
                LOG.debug("替换后\r\n" + ret[0]);
                LOG.debug("下沉后\r\n" + ret[1]);
                tempStr = ret[0];

                if (StringUtils.isNotEmpty(ret[1])) {
                    StringBuffer javaScrip = new StringBuffer("<script type=\"text/javascript\">\r\n");
                    javaScrip.append(ret[1]);
                    javaScrip.append("</script>\r\n");
                    lyt.put("footerJS", javaScrip);
                }

                ret = footerJavaScriptLink(tempStr);
                LOG.debug("替换链接后\r\n" + ret[0]);
                LOG.debug("下沉链接后\r\n" + ret[1]);
                tempStr = ret[0];
                if (StringUtils.isNotEmpty(ret[1])) {
                    lyt.put("footerJSLink", ret[1]);
                }

                //获取head
                String head = getHtmlTagContent("head", tempStr);
                LOG.debug("获取head\r\n" + head);
                if (StringUtils.isNotEmpty(head)) {
                    //获取title
                    String title = getHtmlTagContent("title", head);
                    if (StringUtils.isNotEmpty(title)) {
                        lyt.put("title", title.trim());
                    }

                    //head剔除title
                    head = replaceHtmlTagContent("title", head, "");
                    if (StringUtils.isNotEmpty(head)) {
                        lyt.put("head", head.trim());
                    }
                }
                //获取body
                String body = getHtmlTagContent("body", tempStr);
                if (StringUtils.isNotEmpty(body)) {
                    lyt.put("body", body.trim());
                }
                Template layout = cfg.getTemplate(ftlTemplate.getLayout()+".ftl");
                SysConfig sysConfig = sysConfigService.getSysConfig("ftl","template_out_dir");
                File file = new File(sysConfig.getKeyValue()+"/"+ftlTemplate.getLocation()+".html");
                Writer out = new OutputStreamWriter(new FileOutputStream(file),"utf-8");
                HashMap<String, Object> page = new HashMap<String, Object>();
                page.put("lyt", lyt);
                layout.process(page, out);
                // temp.process(null,out);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TemplateException e) {
                e.printStackTrace();
            }
        }
        Map<String, Object> ret = new HashMap<String, Object>();
        ret.put("msg", "ok");
        return ret;
    }


    public static String replaceHtmlTagContent(String tag,String html,String replaceStr){
        String pattern = "<[\\s]*"+tag+"[\\s]*.*?>(.*?)</[\\s]*"+tag+"[\\s]*>";
        Pattern r = Pattern.compile(pattern,Pattern.DOTALL);
        Matcher m = r.matcher(html);
        return  m.replaceAll(replaceStr);
    }

    public static String getHtmlTagContent(String tag,String html){
        String pattern = "<[\\s]*"+tag+"[\\s]*.*?>(.*?)</[\\s]*"+tag+"[\\s]*>";
        Pattern r = Pattern.compile(pattern,Pattern.DOTALL);
        Matcher m = r.matcher(html);
        if(m.find()){
            return m.group(1);
        }
        return  "";
    }

    public static String[] footerJavaScript(String html){
        String  pattern = "<[\\s]*script(?:(?!src).)*?[\\s]+footer(?:(?!src).)*?>(.*?)</[\\s]*script[\\s]*>";
        Pattern r = Pattern.compile(pattern,Pattern.DOTALL);
        Matcher m = r.matcher(html);
        StringBuffer js=new StringBuffer();

        while (m.find()){
            js.append(m.group(1));
        }

        String[] ret = new String[2];
        ret[0]=m.replaceAll("");
        ret[1]=js.toString();
        return ret;
    }

    public static String[] footerJavaScriptLink(String html){
        String  pattern = "<[\\s]*script.*?[\\s]+footer.*?>(?:(?:[\\s]*?)</[\\s]*script[\\s]*>)?";
        Pattern r = Pattern.compile(pattern,Pattern.DOTALL);
        Matcher m = r.matcher(html);
        StringBuffer jsLink=new StringBuffer();
        while (m.find()){
            jsLink.append(m.group().replaceAll("\\sfooter",""));
            jsLink.append("\r\n");
        }

        String[] ret = new String[2];
        ret[0]=m.replaceAll("");
        ret[1]=jsLink.toString();
        return ret;
    }

}
